#ifndef GVL_CONTAINERS_LIST_H
#define GVL_CONTAINERS_LIST_H

typedef struct gvl_list_node_
{
	struct gvl_list_node_* next;
	struct gvl_list_node_* prev;
} gvl_list_node;

typedef struct gvl_list_
{
	gvl_list_node sentinel;
} gvl_list;

GVL_INLINE void gvl_list_init(gvl_list* self)
{
	self->sentinel.next = &self->sentinel;
	self->sentinel.prev = &self->sentinel;
}

#define gvl_list_last(x) ((x)->sentinel.prev)
#define gvl_list_first(x) ((x)->sentinel.next)

GVL_INLINE void gvl_list_insert(gvl_list* self, gvl_list_node* node, gvl_list_node* after)
{
	gvl_list_node* after_next = after->next;
	
	after_next->prev = node;
	after->next = node;
	node->next = after_next;
	node->prev = after;
}

GVL_INLINE void gvl_list_push_back(gvl_list* self, gvl_list_node* node)
{
	gvl_list_node* last = gvl_list_last(self);
	
	gvl_list_insert(self, node, last);
}

GVL_INLINE void gvl_list_unlink(gvl_list_node* node)
{
	gvl_list_node* node_prev = node->prev;
	gvl_list_node* node_next = node->next;
	node_prev->next = node_next;
	node_next->prev = node_prev;
}

#endif // GVL_CONTAINERS_LIST_H
